<h1>获取参数</h1>

<p>我们经常需要获取用户传递的数据，包括 Get、POST 等方式的请求，beego 里面会自动解析这些数据，你可以通过如下方式获取数据：</p>

<ul>
    <li>GetString(key string) string<br /></li>
    <li>GetStrings(key string) []string<br /></li>
    <li>GetInt(key string) (int64, error)<br /></li>
    <li>GetBool(key string) (bool, error)<br /></li>
    <li>GetFloat(key string) (float64, error)<br /></li>
</ul>

<p>使用例子如下：</p>

<pre lang="go"><code>func (this *MainController) Post() {
    jsoninfo := this.GetString(&quot;jsoninfo&quot;)
    if jsoninfo == &quot;&quot; {
        this.Ctx.WriteString(&quot;jsoninfo is empty&quot;)
        return
    }
}
</code></pre>

<p>如果你需要的数据可能是其他类型的，例如是 int 类型而不是 int64，那么你需要这样处理：</p>

<pre lang="go"><code>func (this *MainController) Post() {
    id := this.Input().Get(&quot;id&quot;)
    intid, err := strconv.Atoi(id)
}
</code></pre>

<p>更多其他的 request 的信息，用户可以通过 <code>this.Ctx.Request</code> 获取信息，关于该对象的属性和方法参考手册 <a href="http://gowalker.org/net/http#Request">Request</a>。</p>

<h2>直接解析到 struct</h2>

<p>如果要把表单里的内容赋值到一个 struct 里，除了用上面的方法一个一个获取再赋值外，beego 提供了通过另外一个更便捷的方式，就是通过 struct 的字段名或 tag 与表单字段对应直接解析到 struct。</p>

<p>定义 struct：</p>

<pre lang="go"><code>type user struct {
    Id    int         `form:&quot;-&quot;`
    Name  interface{} `form:&quot;username&quot;`
    Age   int         `form:&quot;age&quot;`
    Email string
}
</code></pre>

<p>表单：</p>

<pre><code>&lt;form id=&quot;user&quot;&gt;
    名字：&lt;input name=&quot;username&quot; type=&quot;text&quot; /&gt;
    年龄：&lt;input name=&quot;age&quot; type=&quot;text&quot; /&gt;
    邮箱：&lt;input name=&quot;Email&quot; type=&quot;text&quot; /&gt;
    &lt;input type=&quot;submit&quot; value=&quot;提交&quot; /&gt;
&lt;/form&gt;
</code></pre>

<p>Controller 里解析：</p>

<pre lang="go"><code>func (this *MainController) Post() {
    u := user{}
    if err := this.ParseForm(&amp;u); err != nil {
        //handle error
    }
}
</code></pre>

<p>注意：</p>

<ul>
    <li>StructTag form 的定义和 <a href="../view/view.md#renderform-%E4%BD%BF%E7%94%A8">renderform方法</a> 共用一个标签<br /></li>
    <li>定义 struct 时，字段名后如果有 form 这个 tag，则会以把 form 表单里的 name 和 tag 的名称一样的字段赋值给这个字段，否则就会把 form 表单里与字段名一样的表单内容赋值给这个字段。如上面例子中，会把表单中的 username 和 age 分别赋值给 user 里的 Name 和 Age 字段，而 Email 里的内容则会赋给 Email 这个字段。<br /></li>
    <li>调用 Controller ParseForm 这个方法的时候，传入的参数必须为一个 struct 的指针，否则对 struct 的赋值不会成功并返回 <code>xx must be  a struct pointer</code> 的错误。<br /></li>
    <li>如果要忽略一个字段，有两种办法，一是：字段名小写开头，二是：<code>form</code> 标签的值设置为 <code>-</code><br /></li>
</ul>

<h2>获取 Request Body 里的内容</h2>

<p>在 API 的开发中，我们经常会用到 <code>JSON</code> 或 <code>XML</code> 来作为数据交互的格式，如何在 beego 中获取 Request Body 里的 JSON 或 XML 的数据呢？</p>

<ol>
    <li>在配置文件里设置 <code>copyrequestbody = true</code><br /></li>
    <li>在 Controller 中<br /></li>
</ol>

<pre lang="go"><code>func (this *ObjectController) Post() {
    var ob models.Object
    var err error
    if err = json.Unmarshal(this.Ctx.Input.RequestBody, &amp;ob); err == nil {
        objectid := models.AddOne(ob)
        this.Data[&quot;json&quot;] = &quot;{\&quot;ObjectId\&quot;:\&quot;&quot; + objectid + &quot;\&quot;}&quot;
    } else {
        this.Data[&quot;json&quot;] = err.Error()
    }
    this.ServeJSON()
}
</code></pre>

<h2>文件上传</h2>

<p>在 beego 中你可以很容易的处理文件上传，就是别忘记在你的 form 表单中增加这个属性 <code>enctype=&quot;multipart/form-data&quot;</code>，否则你的浏览器不会传输你的上传文件。</p>

<p>文件上传之后一般是放在系统的内存里面，如果文件的 size 大于设置的缓存内存大小，那么就放在临时文件中，默认的缓存内存是 64M，你可以通过如下来调整这个缓存内存大小:</p>

<pre><code>beego.MaxMemory = 1&lt;&lt;22
</code></pre>

<p>或者在配置文件中通过如下设置：</p>

<pre><code>maxmemory = 1&lt;&lt;22
</code></pre>

<p>Beego 提供了两个很方便的方法来处理文件上传：</p>

<ul>
    <li><p>GetFile(key string) (multipart.File, *multipart.FileHeader, error)</p>

        <p>该方法主要用于用户读取表单中的文件名 <code>the_file</code>，然后返回相应的信息，用户根据这些变量来处理文件上传：过滤、保存文件等。</p></li>

    <li><p>SaveToFile(fromfile, tofile string) error</p>

        <p>该方法是在 GetFile 的基础上实现了快速保存的功能<br />
            fromfile 是提交时候的 html 表单中的 name</p></li>
</ul>

<pre lang="html"><code>&lt;form enctype=&quot;multipart/form-data&quot; method=&quot;post&quot;&gt;
    &lt;input type=&quot;file&quot; name=&quot;uploadname&quot; /&gt;
    &lt;input type=&quot;submit&quot;&gt;
&lt;/form&gt;
</code></pre>

<p>保存的代码例子如下：</p>

<pre lang="go"><code>func (c *FormController) Post() {
    f, h, err := c.GetFile(&quot;uploadname&quot;)
    if err != nil {
        log.Fatal(&quot;getfile err &quot;, err)
    }
    defer f.Close()
    c.SaveToFile(&quot;uploadname&quot;, &quot;static/upload/&quot; + h.Filename) // 保存位置在 static/upload, 没有文件夹要先创建

}
</code></pre>

<h2>数据绑定</h2>

<p>支持从用户请求中直接数据 bind 到指定的对象,例如请求地址如下</p>

<pre><code>?id=123&amp;isok=true&amp;ft=1.2&amp;ol[0]=1&amp;ol[1]=2&amp;ul[]=str&amp;ul[]=array&amp;user.Name=astaxie
</code></pre>

<pre><code>var id int
this.Ctx.Input.Bind(&amp;id, &quot;id&quot;)  //id ==123

var isok bool
this.Ctx.Input.Bind(&amp;isok, &quot;isok&quot;)  //isok ==true

var ft float64
this.Ctx.Input.Bind(&amp;ft, &quot;ft&quot;)  //ft ==1.2

ol := make([]int, 0, 2)
this.Ctx.Input.Bind(&amp;ol, &quot;ol&quot;)  //ol ==[1 2]

ul := make([]string, 0, 2)
this.Ctx.Input.Bind(&amp;ul, &quot;ul&quot;)  //ul ==[str array]

user struct{Name}
this.Ctx.Input.Bind(&amp;user, &quot;user&quot;)  //user =={Name:&quot;astaxie&quot;}
</code></pre>
